; gdtnasm.inc   symbols and macros for building descriptors
; Version 1.0 March 5, 1998
; Sample code
; by John S. Fine  johnfine@erols.com
; I do not place any restrictions on your use of this source code
; I do not provide any warranty of the correctness of this source code
;_____________________________________________________________________________
;
;  This is a quick kludge to do in a single module program, some of the
;  things that my gdt.inc does in a program linked with JLOC
;_____________________________________________________________________________
;
; The desc macro pieces together a segment descriptor.
;
; desc  offset, selector, flags     ;For gate descriptors
; desc  base, limit, flags	    ;For all other descriptors
;
;  base    is the full 32 bit base address of the segment
;  limit   is one less than the segment length in 1 or 4K byte units
;  flags   the sum of all the "D_" equates which apply (for call gates, you
;          also add the "parameter dword count" to flags).
;_____________________________________________________________________________

;Each descriptor should have exactly one of next 8 codes to define the type of
;descriptor
D_LDT		EQU	 200h	;LDT segment
D_TASK		EQU	 500h	;Task gate
D_TSS		EQU	 900h	;TSS
D_CALL		EQU	0C00h	;386 call gate
D_INT		EQU	0E00h	;386 interrupt gate
D_TRAP		EQU	0F00h	;386 trap gate
D_DATA		EQU	1000h	;Data segment
D_CODE		EQU	1800h	;Code segment

;Descriptors may include the following as appropriate:
D_DPL3		EQU	6000h	;DPL3 or mask for DPL
D_DPL2		EQU	4000h
D_DPL1		EQU	2000h
D_PRESENT	EQU	8000h	;Present
D_NOT_PRESENT	EQU	8000h	;Not Present
				;Note, the PRESENT bit is set by default
				;Include NOT_PRESENT to turn it off
				;Do not specify D_PRESENT

;Segment descriptors (not gates) may include:
D_ACC		EQU	 100h	;Accessed (Data or Code)

D_WRITE		EQU	 200h	;Writable (Data segments only)
D_READ		EQU	 200h	;Readable (Code segments only)
D_BUSY		EQU	 200h	;Busy (TSS only)

D_EXDOWN	EQU	 400h	;Expand down (Data segments only)
D_CONFORM	EQU	 400h	;Conforming (Code segments only)

D_BIG		EQU	  40h	;Default to 32 bit mode (USE32)
D_BIG_LIM	EQU	  80h	;Limit is in 4K units

%define work_around_nasm_prepend_bug

%macro desc 3
work_around_nasm_prepend_bug
%if (%3) & (~(%3)>>2) & 0x400   ;Gate
	dw	%1
	dw	%2
	dw	(%3)+D_PRESENT
	dw	(%1) >> 16
%else                           ;Not a gate
	dw	%2
	dw	%1
	db	(%1) >> 16
	db	((%3)+D_PRESENT) >> 8
	db	(%3) + ((%2) >> 16)
	db	(%1) >> 24
%endif
%endmacro

;-----------------------------------------------------------------------------
;
;  A gate is identified as any descriptor whose flags has bit 10 set and 
;  bit 12 clear.
;
;  For a gate, the following rearrangement occurs:
;
;  subField                Final location
;  ------------------      --------------
;  Selector[0..15]             16..31
;  Minor control bits          32..39
;  Major control bits          40..47
;  Offset[0..15]                0..15
;  Offset[16..31]              48..63
;
;  For non-gates the following rearrangement occurs:
;
;  subField                Final location
;  ------------------      --------------
;  Limit[0..15]                 0..15
;  Limit[16..19]               48..51
;  Minor control bits          52..57
;  Major control bits          40..47
;  Base[0..23]                 16..39
;  Base[24..31]                56..63
;
;  The last parameter to the desc macro contains all the control bits
;  combined.  It is generated by adding together the appropriate
;  D_ constants.  For all descriptors, it has the major control bits in D_
;  bits 8 to 15.  The minor control bits are in either D_ bits 0 to 7 or bits
;  4 to 7 depending on the type of descriptor.
;_____________________________________________________________________________

